Crea un'esperienza di accesso che utilizzi le passkey, ma che sia compatibile anche con gli utenti che utilizzano password esistenti.
Questa guida spiega come utilizzare la compilazione automatica dei moduli per consentire agli utenti di accedere con le passkey insieme alle password. L'utilizzo della compilazione automatica dei moduli crea un'esperienza di accesso unificata, semplificando la transizione dalle password al metodo di autenticazione delle passkey più sicuro e intuitivo.
Scopri come implementare l'interfaccia utente condizionale di WebAuthn per supportare sia gli utenti con passkey sia quelli con password con un'esperienza utente minima nei moduli di accesso esistenti.
Perché utilizzare la compilazione automatica dei moduli per accedere con una passkey?
Le passkey consentono agli utenti di accedere ai siti web utilizzando l'impronta, il volto o il PIN del dispositivo.
Se tutti gli utenti avessero passkey, il flusso di autenticazione potrebbe essere un singolo pulsante di accesso. Se tocca il pulsante, l'utente può verificare direttamente l'account con la serratura dello schermo e accedere.
Tuttavia, il passaggio dalle password alle passkey presenta delle sfide. I siti web devono supportare sia gli utenti con password sia quelli con passkey durante questo periodo. Aspettarsi che gli utenti ricordino quali siti utilizzano le passkey e chiedere loro di scegliere in anticipo un metodo di accesso crea un'esperienza utente negativa.
Anche le passkey sono una nuova tecnologia e può essere difficile spiegarle in modo chiaro. L'utilizzo dell'interfaccia di compilazione automatica familiare aiuta a risolvere sia la sfida della transizione sia la necessità di familiarità da parte dell'utente.
Utilizzare l'interfaccia utente condizionale
Per supportare in modo efficace gli utenti che utilizzano sia le passkey sia le password, includi le passkey nei suggerimenti di compilazione automatica del modulo. Questo approccio utilizza l' interfaccia utente condizionale, una funzionalità dello standard WebAuthn.
Quando l'utente attiva il campo di immissione del nome utente, viene visualizzata una finestra di dialogo di compilazione automatica che suggerisce le passkey memorizzate insieme alle password salvate. L'utente può selezionare una passkey o una password e procedere con l'accesso utilizzando il blocco schermo del dispositivo se sceglie una passkey.
In questo modo, gli utenti possono accedere al tuo sito web con il modulo di accesso esistente, ma con il vantaggio aggiuntivo della sicurezza delle passkey, se ne hanno una.
Come funziona l'autenticazione con passkey
Per autenticarti con una passkey, utilizza l'API WebAuthn.
I quattro componenti di un flusso di autenticazione con passkey sono:
- Backend: memorizza i dettagli dell'account utente, inclusa la chiave pubblica.
- Frontend: comunica con il browser e recupera i dati necessari dal backend.
- Browser: esegue il codice JavaScript e interagisce con l'API WebAuthn.
- Fornitore di passkey: crea e memorizza la passkey. Di solito si tratta di un gestore delle password come Gestore delle password di Google o di un token di sicurezza.

La procedura di autenticazione delle passkey segue questo flusso:
- L'utente visita la pagina di accesso e il frontend richiede una verifica dell'autenticazione al backend.
- Il backend genera e restituisce una verifica WebAuthn associata all'account dell'utente.
- Il frontend chiama
navigator.credentials.get()
con la verifica per avviare l'autenticazione utilizzando il browser. - Il browser, interagendo con il fornitore di passkey, chiede all'utente di selezionare una passkey (spesso utilizzando una finestra di dialogo di compilazione automatica attivata mettendo in primo piano il campo di accesso) e di verificare la propria identità utilizzando il blocco schermo o i dati biometrici del dispositivo.
- Dopo la verifica dell'utente, il fornitore di passkey firma la verifica e il browser restituisce la credenziale della chiave pubblica risultante (inclusa la firma) al frontend.
- Il frontend invia questa credenziale al backend.
- Il back-end verifica la firma della credenziale in base alla chiave pubblica memorizzata dell'utente. Se la verifica va a buon fine, il backend fa accedere l'utente.
Eseguire l'autenticazione con una passkey tramite la compilazione automatica dei moduli
Per avviare l'autenticazione con passkey utilizzando la compilazione automatica dei moduli, effettua una chiamata get
WebAuthn condizionale al caricamento della pagina di accesso. Questa chiamata a
navigator.credentials.get()
include l'opzione mediation: 'conditional'
.
Una richiesta condizionale all'APInavigator.credentials.get()
WebAuthn non mostra immediatamente l'interfaccia utente. Al contrario, rimane in uno stato di attesa finché l'utente non interagisce con il prompt di compilazione automatica del campo del nome utente. Se l'utente seleziona una passkey, il browser risolve la promessa in attesa con una credenziale per l'accesso, bypassando l'invio del modulo tradizionale. Se l'utente sceglie una password, la promessa non viene risolta e il flusso di accesso con password standard continua. È quindi responsabilità della pagina far accedere l'utente.
Annotare il campo di immissione del modulo
Per attivare l'inserimento automatico delle passkey, aggiungi l'attributo autocomplete
al campo username input
del modulo. Includi sia username
sia webauthn
come valori separati da spazi.
<input type="text" name="username" autocomplete="username webauthn" autofocus>
L'aggiunta di autofocus
a questo campo attiva automaticamente la richiesta di inserimento automatico al caricamento della pagina, mostrando immediatamente le password e le passkey disponibili.
Rilevamento di funzionalità
Prima di invocare una chiamata all'API WebAuthn condizionale, controlla se:
- Il browser supporta WebAuthn con
PublicKeyCredential
.
- Il browser supporta l'interfaccia utente condizionale di WebAuthn con
PublicKeyCredential.isConditionalMediationAvailable()
.
Lo snippet seguente mostra come verificare se il browser supporta queste funzionalità:
// Availability of window.PublicKeyCredential means WebAuthn is usable.
if (window.PublicKeyCredential &&
PublicKeyCredential.isConditionalMediationAvailable) {
// Check if conditional mediation is available.
const isCMA = await PublicKeyCredential.isConditionalMediationAvailable();
if (isCMA) {
// Call WebAuthn authentication
}
}
Recuperare le informazioni dal back-end
Il backend deve fornire diverse opzioni al frontend per avviare la chiamatanavigator.credentials.get()
. In genere, queste opzioni vengono recuperate come oggetto JSON da un endpoint sul server.
Le proprietà principali dell'oggetto options includono:
challenge
: una verifica generata dal server in un ArrayBuffer (in genere codificata in Base64URL per il trasporto JSON). Questo è essenziale per prevenire gli attacchi di replay. Il server deve generare una nuova verifica per ogni tentativo di accesso e deve annullarla dopo poco tempo o se un tentativo non va a buon fine.allowCredentials
: un array di descrittori delle credenziali. Passa un array vuoto. Il browser elenca tutte le credenziali per ilrpId
specificato.userVerification
: specifica la tua preferenza per la verifica dell'utente, ad esempio il blocco schermo del dispositivo. Il valore predefinito e consigliato è"preferred"
. I valori possibili sono:"required"
: la verifica dell'utente deve essere eseguita dall'autenticatore (ad esempio PIN o dati biometrici). L'operazione non va a buon fine se non è possibile eseguire la verifica."preferred"
: l'autenticatore tenta la verifica dell'utente, ma l'operazione può essere eseguita anche senza."discouraged"
: se possibile, l'autenticatore deve evitare la verifica dell'utente.
rpId
: il tuo ID terza parte, in genere il dominio del tuo sito web (ad esempioexample.com
). Questo valore deve corrispondere esattamente all'rp.id
utilizzato quando è stata creata la credenziale passkey.
Il server deve creare questo oggetto opzioni. I valori ArrayBuffer
(come challenge
) devono essere codificati in Base64URL per il trasporto JSON. Sul frontend,
dopo aver analizzato il JSON, utilizza PublicKeyCredential.parseRequestOptionsFromJSON()
per convertire l'oggetto (inclusa la decodifica delle stringhe Base64URL) nel formato
navigator.credentials.get()
previsto.
Il seguente snippet di codice mostra come recuperare e decodificare le informazioni necessarie per l'autenticazione con una passkey.
// Fetch an encoded PubicKeyCredentialRequestOptions from the server.
const _options = await fetch('/webauthn/signinRequest');
// Deserialize and decode the PublicKeyCredentialRequestOptions.
const decoded_options = JSON.parse(_options);
const options = PublicKeyCredential.parseRequestOptionsFromJSON(decoded_options);
...
Chiama l'API WebAuthn con il flag conditional
per autenticare l'utente
Dopo aver preparato l'oggetto publicKeyCredentialRequestOptions
(chiamato
options
nel codice di esempio di seguito), chiama
navigator.credentials.get()
per avviare l'autenticazione con passkey condizionale.
// To abort a WebAuthn call, instantiate an AbortController.
const abortController = new AbortController();
// Invoke WebAuthn to authenticate with a passkey.
const credential = await navigator.credentials.get({
publicKey: options,
signal: abortController.signal,
// Specify 'conditional' to activate conditional UI
mediation: 'conditional'
});
Parametri chiave per questa chiamata:
publicKey
: deve essere l'oggettopublicKeyCredentialRequestOptions
(chiamatooptions
nell'esempio) recuperato dal server e elaborato nel passaggio precedente.signal
: l'invio di un indicatoreAbortController
(ad esempioabortController.signal
) ti consente di annullare la richiestaget()
in modo programmatico. Questa operazione è utile quando vuoi richiamare un'altra chiamata WebAuthn.mediation: 'conditional'
: questo è il flag fondamentale che rende condizionale la chiamata WebAuthn. Indica al browser di attendere l'interazione dell'utente con una richiesta di compilazione automatica anziché mostrare immediatamente una finestra di dialogo modale.
Invia la credenziale della chiave pubblica restituita al server RP
Se l'utente seleziona una passkey e verifica la propria identità (ad esempio utilizzando il blocco schermo del dispositivo), la promessa navigator.credentials.get()
viene risolta. Verrà restituito un oggetto PublicKeyCredential
al frontend.
La promessa può essere rifiutata per diversi motivi. Devi gestire questi errori
nel codice controllando la proprietà name
dell'oggetto Error
:
NotAllowedError
: l'utente ha annullato l'operazione o non è stata selezionata alcuna passkey.AbortError
: l'operazione è stata interrotta, probabilmente dal tuo codice che utilizza unAbortController
.- Altre eccezioni: si è verificato un errore imprevisto. In genere il browser mostra all'utente una finestra di dialogo di errore.
L'oggetto PublicKeyCredential
contiene diverse proprietà. Le proprietà principali
pertinenti per l'autenticazione includono:
id
: l'ID con codifica base64url della credenziale della passkey autenticata.rawId
: una versione ArrayBuffer dell'ID credenziale.response.clientDataJSON
: un ArrayBuffer di dati del cliente. Questo campo contiene informazioni come la verifica e l'origine che il server deve verificare.response.authenticatorData
: un ArrayBuffer di dati dell'autenticatore. Questo campo include informazioni come l'ID RP.response.signature
: un ArrayBuffer contenente la firma. Questo valore è il nucleo della credenziale e il server deve verificare questa firma utilizzando la chiave pubblica memorizzata per la credenziale .response.userHandle
: un ArrayBuffer contenente l'ID utente fornito durante la registrazione della passkey.authenticatorAttachment
: indica se l'autenticatore fa parte del dispositivo client (platform
) o è esterno (cross-platform
). Un allegatocross-platform
può verificarsi se l'utente ha eseguito l'accesso con uno smartphone. In questi casi, ti consigliamo di chiedere all'utente di creare una passkey sul dispositivo attuale per praticità futura.type
: questo campo è sempre impostato su"public-key"
.
Per inviare questo oggetto PublicKeyCredential
al tuo backend, chiama prima il metodo
.toJSON()
. Questo metodo crea una versione serializzabile in JSON della credenziale, che gestisce correttamente la conversione delle proprietà ArrayBuffer
(come rawId
, clientDataJSON
, authenticatorData
, signature
e userHandle
) in stringhe con codifica Base64URL. Quindi, utilizza JSON.stringify()
per
convertire questo oggetto in una stringa e inviarlo nel corpo della richiesta al
server.
...
// Encode and serialize the PublicKeyCredential.
const _result = credential.toJSON();
const result = JSON.stringify(_result);
// Encode and send the credential to the server for verification.
const response = await fetch('/webauthn/signinResponse', {
method: 'post',
credentials: 'same-origin',
body: result
});
Verifica la firma
Quando il server di backend riceve la credenziale della chiave pubblica, deve verificarne l'autenticità. Ciò comporta:
- Analisi dei dati delle credenziali.
- Viene cercata la chiave pubblica memorizzata associata a
id
della credenziale. - Verificare il
signature
ricevuto rispetto alla chiave pubblica memorizzata. - Convalida di altri dati, come la verifica e l'origine.
Ti consigliamo di utilizzare una libreria FIDO/WebAuthn lato server per gestire queste operazioni cryptographic in modo sicuro. Puoi trovare le librerie open source nel repository GitHub di awesome-webauthn.
Se la firma e tutte le altre affermazioni sono valide, il server può far accedere l'utente. Per i passaggi dettagliati della convalida lato server, consulta Autenticazione delle passkey lato server
Segnale se le credenziali corrispondenti non vengono trovate nel backend
Se il server di backend non riesce a trovare una credenziale con un ID corrispondente durante l'accesso, l'utente potrebbe aver eliminato in precedenza questa passkey dal tuo server, ma non dal proprio provider di passkey. Questa mancata corrispondenza può creare confusione nell'esperienza utente se il fornitore di passkey continua a suggerire una passkey che non funziona più con il tuo sito. Per migliorare la situazione, devi segnalare al provider di passkey di rimuovere la passkey orfana.
Puoi utilizzare il metodo PublicKeyCredential.signalUnknownCredential()
, che fa parte dell'API Webauthn Signal, per informare il fornitore di passkey che la credenziale specificata è stata rimossa o non esiste. Chiama questo metodo statico lato client se il tuo server indica (ad esempio con un codice di stato HTTP specifico come 404) che un ID credenziale presentato è sconosciuto. Fornisci a questo metodo l'ID RP e l'ID della credenziale sconosciuta. Il provider della passkey, se supporta l'indicatore, deve rimuovere la passkey.
// Detect authentication failure due to lack of the credential
if (response.status === 404) {
// Feature detection
if (PublicKeyCredential.signalUnknownCredential) {
await PublicKeyCredential.signalUnknownCredential({
rpId: "example.com",
credentialId: "vI0qOggiE3OT01ZRWBYz5l4MEgU0c7PmAA" // base64url encoded credential ID
});
} else {
// Encourage the user to delete the passkey from the password manager nevertheless.
...
}
}
Dopo l'autenticazione
A seconda di come l'utente ha eseguito l'accesso, suggeriamo diversi flussi da seguire.
Se l'utente ha eseguito l'accesso senza una passkey
Se l'utente ha eseguito l'accesso al tuo sito web senza una passkey, è possibile che non ne abbia una registrata per quell'account o sul suo dispositivo attuale. È un momento opportuno per incoraggiare la creazione di passkey. Valuta i seguenti approcci:
- Esegui l'upgrade delle password alle passkey: utilizza la creazione condizionale, una funzionalità WebAuthn che consente al browser di creare automaticamente una passkey per l'utente dopo un accesso con password andato a buon fine. Ciò può migliorare notevolmente l'adozione delle passkey semplificando la procedura di creazione. Scopri come funziona e come implementarlo in Aiutare gli utenti ad adottare le passkey più facilmente
- Richiedi manualmente la creazione di una passkey: incoraggia gli utenti a creare una passkey. Questa operazione può essere efficace dopo che un utente ha completato una procedura di accesso più complessa, come l'autenticazione a più fattori (MFA). Tuttavia, evita richieste eccessive, che possono essere invadenti per l'esperienza utente".
Per scoprire come incoraggiare gli utenti a creare una passkey e conoscere altre buone pratiche, consulta gli esempi su come comunicare le passkey agli utenti.
Se l'utente ha eseguito l'accesso con una passkey
Dopo che un utente ha eseguito l'accesso con una passkey, hai diverse opportunità per migliorare ulteriormente la sua esperienza e mantenere la coerenza dell'account.
Incoraggiare la creazione di una nuova passkey dopo un'autenticazione su più dispositivi
Se un utente accede con una passkey utilizzando un meccanismo cross-device (ad esempio, eseguendo la scansione di un codice QR con il telefono), la passkey utilizzata potrebbe non essere memorizzata localmente sul dispositivo su cui sta accedendo. Questo si verifica se:
- Hanno una passkey, ma un fornitore di passkey che non supporta il browser o il sistema operativo di accesso.
- L'utente ha perso l'accesso al fornitore della passkey sul dispositivo di accesso, ma una passkey è ancora disponibile su un altro dispositivo.
In questa situazione, ti consigliamo di chiedere all'utente di creare una nuova passkey sul
dispositivo corrente. In questo modo, in futuro non dovrà ripetere la procedura di accesso su più dispositivi. Per determinare se l'utente ha eseguito l'accesso utilizzando una
passkey cross-device, controlla la proprietà authenticatorAttachment
della
credenziale. Se il valore è "cross-platform"
, indica un'autenticazione su più dispositivi. In questo caso, spiega la praticità di creare una nuova passkey e guidalo nella procedura di creazione.
Sincronizzare i dettagli della passkey con il fornitore utilizzando gli indicatori
Per garantire coerenza e una migliore esperienza utente, la tua terza parte attendibile (RP) può utilizzare l'API WebAuthn Signals per comunicare aggiornamenti sulle credenziali e sulle informazioni dell'utente al fornitore di passkey.
Ad esempio, per mantenere aggiornato l'elenco delle passkey di un utente del fornitore di passkey, mantieni sincronizzate le credenziali sul backend. Puoi indicare che una passkey non esiste più in modo che i fornitori di passkey possano rimuovere quelle non necessarie.
Analogamente, puoi segnalare se un utente aggiorna il proprio nome utente o nome visualizzato sul tuo servizio per contribuire a mantenere aggiornate le informazioni dell'utente visualizzate dal fornitore delle passkey (ad esempio nelle finestre di dialogo di selezione dell'account).
Per scoprire di più sulle best practice per mantenere coerenti le passkey, consulta Mantenere coerenti le passkey con le credenziali sul server con l'API Signal.
Non chiedere un secondo fattore
Le passkey offrono una protezione integrata e affidabile contro minacce comuni come il phishing. Pertanto, un secondo fattore di autenticazione non aggiunge un valore di sicurezza significativo. ma crea un passaggio non necessario per gli utenti durante l'accesso.
Elenco di controllo
- Consenti agli utenti di accedere con una passkey tramite il riempimento automatico dei moduli.
- Indica quando la credenziale corrispondente di una passkey non viene trovata nel backend.
- Chiedi agli utenti di creare manualmente una passkey se non l'hanno ancora fatto dopo un accesso.
- Crea automaticamente una passkey (creazione condizionale) dopo che l'utente ha eseguito l'accesso con una password (e un secondo fattore).
- Richiedi la creazione di una passkey locale se l'utente ha eseguito l'accesso con una passkey cross-device.
- Indica al fornitore l'elenco delle passkey disponibili e i dettagli dell'utente aggiornati (nome utente, nome visualizzato) dopo l'accesso o quando si verificano modifiche.